package projet.item;

import java.util.ArrayList;

import projet.Tools;

import projet.CustomException;
import projet.dataaccess.DataAccess;
import projet.dataaccess.PathErrorException;
import projet.dataaccess.XML;
import projet.metadata.MetaData;

/**
 * The Item class represents a multi-media item. Information about the item is
 * stored and can be retrieved. This class serves as a superclass for more
 * specific items.
 * 
 * @author CORSINI Pierre, BRUN Sylvain
 * @version December 13, 2009
 */
public abstract class Item {
	public static final int UNDEFID = 0;
	protected String description;
	protected Integer id;
	private Integer ownerID;
	protected String title;
	private ArrayList<Integer> metaDataIds;
	protected String path;

	/**
	 * For inheritance purpose
	 */
	protected Item() {
		this.metaDataIds = new ArrayList<Integer>();
	}

	/**
	 * Create an Item with a give ID, with user input
	 * 
	 * @param id
	 * @throws CustomException
	 */
	public Item(int id) throws CustomException {
		this.metaDataIds = new ArrayList<Integer>();
		this.id = id;
		this.AskEdit();
	}

	/**
	 * Initialise the fields of the item.
	 * 
	 * @param theTitle The title of this item.
	 * @param time The running time of this item.
	 */
	public Item(int id, String theTitle, String comment, String path) {
		this.metaDataIds = new ArrayList<Integer>();
		this.id = id;
		this.title = theTitle;
		this.description = (comment.equals("")) ? "No comment" : comment;
		this.path = path;
		this.ownerID = -1;
	}

	/**
	 * @param dataAccess
	 * @throws PathErrorException
	 */
	public Item(DataAccess dataAccess) throws PathErrorException {
		this.metaDataIds = new ArrayList<Integer>();
		this.description = dataAccess.getElementString("description");
		this.id = dataAccess.getElementInt("id");
		this.ownerID = dataAccess.getElementInt("ownerID");
		this.title = dataAccess.getElementString("title");

		for (DataAccess v : dataAccess.getElements("metaDatas")) {
			this.metaDataIds.add(v.getElementInt(""));
		}
	}


	/**
	 * Ask user to edit fields
	 * 
	 * @throws CustomException
	 */
	public void AskEdit() throws CustomException {
		String buffer;

		// Title
		System.out.print("- Titre: ");
		buffer = Tools.readLineEdit(this.title);
		if (buffer.length() < 1)
			throw new CustomException(
					"Item name must at least have one character !");
		this.title = buffer;

		// Comment
		System.out.print("- Comment: ");
		buffer = Tools.readLineEdit(this.description);
		if (buffer.length() < 1)
			throw new CustomException(
					"Item comment must at least have one character !");
		this.description = buffer;

		// Path
		System.out.print("- Path: ");
		buffer = Tools.readLineEdit(this.path);
		this.path = buffer;
	}

	/**
	 * read the media
	 */
	public abstract void play();

	/**
	 * @return The comment for this item.
	 */
	public String getComment() {
		return this.description;
	}

	/**
	 * Get the item id
	 * 
	 * @return The id
	 */
	public int getId() {
		return this.id;
	}

	/**
	 * Get the owner id
	 * 
	 * @return The id
	 */
	public int getOwnerId() {
		return this.ownerID;
	}

	/**
	 * Get the title
	 * 
	 * @return The title
	 */
	public String getTitle() {
		return this.title;
	}

	public String getPath() {
		return this.path;
	}

	/**
	 * Enter a comment for this item.
	 * 
	 * @param comment The comment to be entered.
	 */
	public void setComment(String comment) {
		this.description = comment;
	}

	/**
	 * Set the item id
	 * 
	 * @param id The id
	 */
	public void setId(int id) {
		this.id = id;
	}

	/**
	 * Set the owner id
	 * 
	 * @param id
	 */
	public void setOwnerId(int id) {
		this.ownerID = id;
	}

	/**
	 * Set the owner id
	 * 
	 * @param id The id
	 */
	public void setTitle(String title) {
		this.title = title;
	}

	/**
	 * Get the metaDatas
	 * 
	 * @return The metaDatas
	 */
	public ArrayList<Integer> getMetaDataIDs() {
		return this.metaDataIds;
	}

	/**
	 * add a MetaData in my metaDatas
	 * 
	 * @param The metaData
	 */
	public void addMetaData(MetaData metaData) {
		this.metaDataIds.add(metaData.getId());
	}

	/**
	 * Remove a MetaData from the list
	 * 
	 * @param id The id of the MetaData to remove
	 */
	public void removeMetaData(Integer id) {
		this.metaDataIds.remove(id);
	}

	/**
	 * Get the metaDatas in String
	 * 
	 * @return The String
	 */
	public String metaDatasToString() {
		String result = " ";
		for (int i = 0; i < this.metaDataIds.size(); ++i)
			result += this.metaDataIds.get(i) + " ";
		return result;
	}

	/**
	 * Convert the item to a DataAccess
	 * 
	 * @return The DataAccess object
	 * @throws PathErrorException
	 */
	public DataAccess toMediaAccess() throws PathErrorException {
		DataAccess dataAccess = new XML();
		dataAccess.setName(this.getClass().getSimpleName().toLowerCase());
		dataAccess.addElement("title", this.title);
		dataAccess.addElement("description", this.description);
		dataAccess.addElement("id", this.id.toString());
		dataAccess.addElement("ownerID", this.ownerID.toString());

		DataAccess medias = dataAccess.moveToPath("metaDatas", true);
		for (Integer i : this.metaDataIds) {
			medias.addElement("meta", i.toString());
		}

		return dataAccess;
	}

	/**
	 * Méthode affichage pour un show
	 */
	public void affichage() {
		Tools.print(2, "ID          : " + this.id);
		Tools.print(2, "Titre       : " + this.title);
		Tools.print(2, "Description : " + this.description);
		if (this.path != "" && this.path != null)
			Tools.print(2, "Path        : " + this.path);
	}

	/**
	 * Print details of this item to the text terminal.
	 */
	@Override
	public String toString() {
		String s = String.format("[Type:%s ID:%d] Name:\"%s\" ", this
				.getClass().getSimpleName(), this.id, this.title);

		if (this.path != null && this.path.length() > 0)
			s += "Path: \"" + this.path + "\"";
		if (this.description != "")
			s += " Comments:\"" + this.description + "\" ";
		return s;
	}
}
